import { dom, RecordOperationType } from '../tool';
import wordCells, { CellType } from '../cells';
import Toolbar from './toolbar';
import DocContainer from './DocContainer';
import './index.less';
import '../template/tableTemplate.less';
import { Modal, Switch } from '../components';

export interface TemplateProps {
    node: HTMLElement;         // 存放表单的父级容器
    mode?: 1 | 2 | 3;   // 模式：1：绘制模式、2：编辑模式、3：查看模式  默认3
    parentTemplate?: any;// 父级模板实例
}

export interface TemplateData {
    border?: string;
    borderColor?: string;
    cellDatas: Array<any>;
}

// 用户自定义属性
export interface AttribType {
    type: number;   // 类型
    fieldName?: string;  // 字段名
    text?: string;  // 文本
    placeholder?: string;   // 提示信息
    defaultValue?: string | number | string[] | number[]; // 默认值
    value?: string | number | string[] | number[]; // 默认值
    disabled?: boolean; // 禁用
    readonly?: boolean;
    rows?: number;
    cols?: number;
    data?: any;
    onChange?: Function;
    columns?: any[];
    list?: any[];
}
export interface CellComponentType {
    new(): CellComponentType;
    type: number;           // 类型
    attrData: AttribType;   // 属性
    parentContainer: Object;// 父级容器实例
    setDisabled: (arg: boolean) => void;   // 
    setVisible: (arg: boolean) => void;   // 
    setReadonly: (arg: boolean) => void;   // 
    setValue: (arg: any) => void;   // 
    getValue: () => any;   // 
    reset: () => void;   // 重置
    getAttribNode: () => HTMLElement; // 设置此组件的属性  返回DOcumentNode
    getAttrData: () => AttribType;    // 获取属性
    sizeChange: () => void;   // 尺寸发生变化调用
    render: () => void;      // 渲染函数
    renderAfter: () => void;  // 渲染后调用
}

export interface DocContainerType {
    new(node: HTMLElement, mode?: 1 | 2 | 3, parentComponent?: any): DocContainerType;
    name: 'docContainer';
    type: 2;
    parentContainer: Object;
    handleCellType: 'add' | 'replace';
    record: RecordOperationType;
    getTemplateData: () => TemplateData;  // 获取容器模板数据
    renderTemplate: (templateData: TemplateData) => void; // 根据模板数据渲染文档
    /**
     * 渲染模板
     * node     渲染模板的元素
     * templateData     渲染模板的模板数据
     */
    render: (node: Node, templateData: TemplateData) => void;
    getValues: () => Object;  // 获取文档填写的数据
    setValues: (value: Object) => void;   // 设定文档数据
    /**
     * 根据字段名设定值
     * fieldName    字段名
     * value        设定的值
     */
    setValue: (fieldName: string, value: any) => void;
    /**
     * 根据属性新增一个元素
     * attribute    元素属性
     * style        元素样式
     */
    addItemByAttrib: (attribute: AttribType, style: any) => void;
    removeItemBySelect: () => void;   // 删除已经选中的单元
    replaceItemBySelect: (attribute: AttribType) => void; // 替换已经选中的元素
    replaceItemByComponent: (id: number, component: CellComponentType) => void;  // 用component组件替换对应id的单元
    cellChange: (arg?: boolean) => void; // 当外部操作导致内部元素尺寸发生变化 需要调用函数  arg是否需要添加新的记录 为true时不添加新纪录
    setCellStyle: (style: any) => void;    // 选中单元设定样式
    showGroupCells: (groupCells: Array<any>) => void; // 高亮一组单元  通过getSelectedCells获取数据
    getSelectedCells: () => Array<any>;   // 获取选中的单元
    // 传入一组单元格数据获取对应组的所有单元
    getGroupCellsInfo: (groupCells: Array<any>, groupName: string) => Array<any>;
    /**
     * 根据组名自动查出这一组当中最后一行，并在最后一行添加新的组成员
     * @param {*} groupName 
     * @param {*} addCellInfos 
     * @param {*} value 给新增的单元格赋值 
     */
    addCellsByGroupName: (groupName: string, addCellInfos: any[], value: any) => void;
    delCellsByGroupName: (groupName: string) => void; // 根据组名删除最后一组的组成员
    getGroupComponents: (groupName: string) => Array<any>; // 获取一组单元的组件
    findGroupCells: (groupName: string) => Array<any>; // 根据组名获取所有组成员
    /**
     * 当选中一个单元后会调用此函数
     * styles: 当前单元格的css样式对象
     * cellInstance: 当前单元格的组件实例
     * docInstance: 当前父级模板的实例  文档实例
     */
    selectedCellChange: (styles: any, cellInstance?: CellType, docInstance?: Object) => void;
}

interface WebDocType {
    new(mode?: 1 | 2 | 3, elementNode?: HTMLElement): WebDocType;
    render: (target: HTMLElement) => HTMLElement;
}

function WebDoc(this: WebDocType, mode = 1, elementNode?: HTMLElement) {
    let doc: DocContainerType;
    let previewDoc: DocContainerType;
    let cellInstance: any;
    let tempInstance: any;
    let toolbar = new Toolbar();
    let previewModal: any;
    const cellClick = (cell: any, ele: any) => {

    };
    const cellNodes = wordCells.map((item: any) => {
        const ele = dom('div', { className: 'doc-cell-item', innerText: item.name });
        ele.onclick = () => {
            cellClick(item, ele);
        }
        ele.draggable = true;
        ele.ondragstart = (event: any) => {
            event.dataTransfer.setData("gkhWordCellId", item.id);
        }
        return ele;
    });
    const cellAttribute = dom('div');

    const selectedCellChange = (style: any, component: any, obj: any) => {
        cellAttribute.innerHTML = "";
        toolbar.setValues(style);
        tempInstance = obj;
        toolbar.delButDisabled(!component);
        if (component) {
            cellInstance = component;
            if (component.getAttribNode) {
                cellAttribute.appendChild(component.getAttribNode());
            }
        }
    }
    toolbar.onChange = (styles) => {
        if (tempInstance) {
            tempInstance.setCellStyle(styles);
        } else {
            doc.setCellStyle(styles);
        }
    }
    toolbar.onDelClick = () => {
        doc.removeItemBySelect();
    }
    toolbar.save = () => {
        console.log(doc.getTemplateData());
    }
    toolbar.preview = ()=>{
        const tData = doc.getTemplateData();
        console.log('template date',tData)
        previewModal.setVisible(true);
        previewDoc.renderTemplate(tData);
    }
    const container = dom('div', { className: 'gkh-web-doc', target: elementNode });
    const topTool = dom('div', { className: 'gkh-web-doc-toolbar', target: container });
    toolbar.render(topTool);
    const replace = new Switch({
        list: [{ key: "add", title: "新增" }, { key: "replace", title: "替换" }],
        onChange: (arg: any) => {
            doc.handleCellType = arg;
            console.log(doc.handleCellType)
        }
    });
    const content = dom('div', { style: "overflow: auto; flex: 1 1 auto; padding: 24px;" });
    const cells = dom('div', {
        className: 'doc-cell-select', childs: [
            dom('div', {
                childs: [
                    dom('div', { child: replace.render(), style: "border-bottom:1px solid #d9d9d9;" }),
                    dom('div', { childs: cellNodes })
                ]
            }),
            dom('div', {
                childs: [
                    dom('h4', { innerText: '属性', style: "border-bottom:1px solid #d9d9d9;" }),
                    dom('div', { child: cellAttribute })
                ]
            })
        ]
    });
    dom('div', { target: container, childs: [content, cells] });
    doc = new DocContainer(content, 1);
    doc.selectedCellChange = selectedCellChange;
    content.addEventListener('scroll', () => {
        doc.cellChange()
    })
    const previewNode = dom('div');
    previewDoc = new DocContainer(previewNode, 2);
    previewModal = new Modal({child: previewNode, target: container});
    this.render = (elementNode1) => {
        if (elementNode1) {
            elementNode1.appendChild(container);
        }
        return container;
    }
    return this;
}


export default WebDoc;